package work.xiaohong.mina.test2.protocol;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderAdapter;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import work.xiaohong.mina.test2.message.GeneralMessage;
import work.xiaohong.mina.test2.message.PlcConstant;

/**
 * @author Kevin
 * @data 4/25/2022 1:08 PM
 * @description 自定义解码器
 **/
public class ProtocolDecoder extends ProtocolDecoderAdapter {

  // 半包情况下剩余的字符串
  private StringBuilder remainString = new StringBuilder();

  @Override
  public void decode(IoSession ioSession, IoBuffer buffer, ProtocolDecoderOutput protocolDecoderOutput) throws Exception {

    GeneralMessage message = new GeneralMessage();


    // 将全部字节数组转字符串
    // limit = position postiont = 0 将缓冲区的数据放入到流中，往往在发送数据之前调用
    buffer.flip();
    byte[] b = new byte [buffer.limit()];
    buffer.get(b);

    StringBuffer stringBuffer = new StringBuffer();

    for (int i = 0; i < b.length; i++) {
      stringBuffer.append((char) b [i]);
    }

    // 拼接上上次剩余的字符串
    String str = remainString.append(stringBuffer).toString();
    remainString = new StringBuilder();

    // 判断当前信息是否是完整的
    boolean isComplete = str.endsWith((char) PlcConstant.MessageEnd + "");

    String[] strings = str.split((char) PlcConstant.MessageEnd + "");

    if (!isComplete){
      // 半包 将最后一个加入到剩余字段数组中
      remainString.append(strings[strings.length-1]);
    }

    // 值得注意的是 切割后的内容将不包括开始符 如10;0;LIFE
    for (int i = 0; i < (isComplete ? strings.length : strings.length-1); i++) {

      String msg =  strings[i];

      // 去除消息标识头
      msg = msg.substring(1);

      // 根据消息分隔符进行切分
      String[] split = msg.split((char) PlcConstant.MessageSeparator + "");

      // 临时储存消息体
      String payLoadStr = null;

      for (int j = 0; j < split.length; j++) {
        String result = split[j].trim();
        switch (j){
          case 0:
            message.setSequenceNumber(Integer.parseInt(result));
            break;
          case 1:
            message.setAcknowledgementRequired(Integer.parseInt(result) == 1);
            break;
          case 2:
            message.setPayloadType(result);
            break;
          default:
            // 剩下的都是载体消息，将剩下的都进行字符串拼接
            if (payLoadStr == null){
              payLoadStr = result;
            }else {
              payLoadStr = payLoadStr + (char) PlcConstant.MessageSeparator + result;
            }
            break;
        }

      }

      // 将消息体字符串转换成对象
      if (payLoadStr != null){

        payLoadStr = new StringBuilder("{").append(payLoadStr).append("}").toString();

        System.out.println(payLoadStr);

        payLoadStr = payLoadStr.replaceAll("=",":")
                .replaceAll("\\{","{\"")
                .replaceAll("}","\"}")
                .replaceAll(";","\",\"")
                .replaceAll(":","\":\"")
                .replaceAll("\"\\[","[")
                .replaceAll("]\"","]");

        JSONObject payLoad = JSON.parseObject(payLoadStr, JSONObject.class);

        message.setPayload(payLoad);

      }

      System.out.println(message);

      // 将解析到的消息写出
//      protocolDecoderOutput.write(message);

    }

  }
}
